home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / TGE129C.ZIP / SOURCE / 320X200.ASM < prev    next >
Assembly Source File  |  1993-08-20  |  36KB  |  1,820 lines

  1. ; 320x200x256
  2. ; Loadable driver for The Graphics Engine
  3. ; Copyright (c) 1993 by Matthew Hildebrand
  4. ; Turbo Assembler syntax
  5.  
  6. IDEAL
  7. P486N            ; 386 code, but we want 486 alignment
  8. MODEL LARGE
  9.  
  10.  
  11. SCREEN_WIDE    =    320
  12. SCREEN_DEEP    =    200
  13. NUM_COLOURS    =    256
  14.  
  15.  
  16.         CODESEG
  17.         ORG    0
  18.  
  19. ;*** Signature
  20.             db    'TGE3'
  21. ;*** Non-I/O functions
  22. _initGraphics        dw    initGraphics        ; initGraphics
  23.             dw    ?
  24. _deInitGraphics        dw    0            ; deInitGraphics
  25.             dw    ?
  26. _setPaletteReg        dw    setPaletteReg        ; setPaletteReg
  27.             dw    ?
  28. _getPaletteReg        dw    getPaletteReg        ; getPaletteReg
  29.             dw    ?
  30. _setBlockPalette    dw    setBlockPalette        ; setBlockPalette
  31.             dw    ?
  32. _getBlockPalette    dw    getBlockPalette        ; getBlockPalette
  33.             dw    ?
  34. _colourCloseTo        dw    0            ; colourCloseTo
  35.             dw    ?
  36. _colourCloseToX        dw    0            ; colourCloseToX
  37.             dw    ?
  38. _imageSize        dw    0            ; imageSize
  39.             dw    ?
  40. _imageSizeDim        dw    0            ; imageSizeDim
  41.             dw    ?
  42. _setPage        dw    0            ; setPage (not implemented yet)
  43.             dw    ?
  44.  
  45. ;*** Currently active I/O functions (filled in by loadGraphDriver())
  46.             dd    20    DUP(?)
  47.  
  48. ;*** Input functions
  49. _getImage_scr        dw    getImage_scr        ; getImage
  50.             dw    ?
  51. _getImage_mem        dw    0
  52.             dw    ?
  53. _getLine_scr        dw    getLine_scr              ; getLine
  54.             dw    ?
  55. _getLine_mem        dw    getLine_mem
  56.             dw    ?
  57. _getPixel_scr        dw    getPixel_scr        ; getPixel
  58.             dw    ?
  59. _getPixel_mem        dw    getPixel_mem
  60.             dw    ?
  61.  
  62. ;*** Output functions
  63. _putImage_scr_copy    dw    putImage        ; putImage
  64.             dw    ?
  65. _putImage_scr_and    dw    0
  66.             dw    ?
  67. _putImage_scr_not    dw    0
  68.             dw    ?
  69. _putImage_scr_or    dw    0
  70.             dw    ?
  71. _putImage_scr_xor    dw    0
  72.             dw    ?
  73. _putImage_mem_copy    dw    0
  74.             dw    ?
  75. _putImage_mem_and    dw    0
  76.             dw    ?
  77. _putImage_mem_not    dw    0
  78.             dw    ?
  79. _putImage_mem_or    dw    0
  80.             dw    ?
  81. _putImage_mem_xor    dw    0
  82.             dw    ?
  83. _putImageInv_scr_copy    dw    putImageInv        ; putImageInv
  84.             dw    ?
  85. _putImageInv_scr_and    dw    0
  86.             dw    ?
  87. _putImageInv_scr_not    dw      0
  88.             dw    ?
  89. _putImageInv_scr_or    dw      0
  90.             dw    ?
  91. _putImageInv_scr_xor    dw    0
  92.             dw    ?
  93. _putImageInv_mem_copy    dw    0
  94.             dw    ?
  95. _putImageInv_mem_and    dw    0
  96.             dw    ?
  97. _putImageInv_mem_not    dw    0
  98.             dw    ?
  99. _putImageInv_mem_or    dw    0
  100.             dw    ?
  101. _putImageInv_mem_xor    dw    0
  102.             dw    ?
  103. _putLine_scr_copy          dw    putLine_scr_copy    ; putLine
  104.             dw    ?
  105. _putLine_scr_and          dw      0
  106.             dw    ?
  107. _putLine_scr_not          dw      0
  108.             dw    ?
  109. _putLine_scr_or          dw      0
  110.             dw    ?
  111. _putLine_scr_xor          dw    0
  112.             dw    ?
  113. _putLine_mem_copy    dw    putLine_mem_copy
  114.             dw    ?
  115. _putLine_mem_and    dw      0
  116.             dw    ?
  117. _putLine_mem_not    dw      0
  118.             dw    ?
  119. _putLine_mem_or        dw      0
  120.             dw    ?
  121. _putLine_mem_xor    dw    0
  122.             dw    ?
  123. _putLineInv_scr_copy       dw    0            ; putLineInv
  124.             dw    ?
  125. _putLineInv_scr_and       dw    0
  126.             dw    ?
  127. _putLineInv_scr_not       dw    0
  128.             dw    ?
  129. _putLineInv_scr_or       dw    0
  130.             dw    ?
  131. _putLineInv_scr_xor       dw    0
  132.             dw    ?
  133. _putLineInv_mem_copy    dw    0
  134.             dw    ?
  135. _putLineInv_mem_and    dw    0
  136.             dw    ?
  137. _putLineInv_mem_not    dw    0
  138.             dw    ?
  139. _putLineInv_mem_or    dw    0
  140.             dw    ?
  141. _putLineInv_mem_xor    dw    0
  142.             dw    ?
  143. _putPixel_scr_copy    dw    putPixel_scr_copy    ; putPixel
  144.             dw    ?
  145. _putPixel_scr_and    dw      putPixel_scr_and
  146.             dw    ?
  147. _putPixel_scr_not    dw      putPixel_scr_not
  148.             dw    ?
  149. _putPixel_scr_or    dw      putPixel_scr_or
  150.             dw    ?
  151. _putPixel_scr_xor    dw    putPixel_scr_xor
  152.             dw    ?
  153. _putPixel_mem_copy    dw    putPixel_mem_copy
  154.             dw    ?
  155. _putPixel_mem_and    dw      putPixel_mem_and
  156.             dw    ?
  157. _putPixel_mem_not    dw    putPixel_mem_not
  158.             dw    ?
  159. _putPixel_mem_or    dw    putPixel_mem_or
  160.             dw    ?
  161. _putPixel_mem_xor    dw    putPixel_mem_xor
  162.             dw    ?
  163. _line_scr_copy        dw    line            ; line
  164.             dw    ?
  165. _line_scr_and        dw      0
  166.             dw    ?
  167. _line_scr_not        dw      0
  168.             dw    ?
  169. _line_scr_or        dw      0
  170.             dw    ?
  171. _line_scr_xor        dw    0
  172.             dw    ?
  173. _line_mem_copy        dw    0
  174.             dw    ?
  175. _line_mem_and        dw    0
  176.             dw    ?
  177. _line_mem_not        dw    0
  178.             dw    ?
  179. _line_mem_or        dw    0
  180.             dw    ?
  181. _line_mem_xor        dw    0
  182.             dw    ?
  183. _horizLine_scr_copy    dw    horizLine_scr_copy    ; horizLine
  184.             dw    ?
  185. _horizLine_scr_and    dw      0
  186.             dw    ?
  187. _horizLine_scr_not    dw      0
  188.             dw    ?
  189. _horizLine_scr_or    dw      0
  190.             dw    ?
  191. _horizLine_scr_xor    dw    0
  192.             dw    ?
  193. _horizLine_mem_copy    dw    horizLine_mem_copy
  194.             dw    ?
  195. _horizLine_mem_and    dw      0
  196.             dw    ?
  197. _horizLine_mem_not    dw      0
  198.             dw    ?
  199. _horizLine_mem_or    dw      0
  200.             dw    ?
  201. _horizLine_mem_xor    dw    0
  202.             dw    ?
  203. _vertLine_scr_copy    dw    0             ; vertLine
  204.             dw    ?
  205. _vertLine_scr_and    dw    0
  206.             dw    ?
  207. _vertLine_scr_not    dw    0
  208.             dw    ?
  209. _vertLine_scr_or    dw    0
  210.             dw    ?
  211. _vertLine_scr_xor    dw    0
  212.             dw    ?
  213. _vertLine_mem_copy    dw    0
  214.             dw    ?
  215. _vertLine_mem_and    dw    0
  216.             dw    ?
  217. _vertLine_mem_not    dw    0
  218.             dw    ?
  219. _vertLine_mem_or    dw    0
  220.             dw    ?
  221. _vertLine_mem_xor    dw    0
  222.             dw    ?
  223. _drawRect_scr_copy    dw    0            ; drawRect
  224.             dw    ?
  225. _drawRect_scr_and    dw    0
  226.             dw    ?
  227. _drawRect_scr_not    dw    0
  228.             dw    ?
  229. _drawRect_scr_or    dw    0
  230.             dw    ?
  231. _drawRect_scr_xor    dw    0
  232.             dw    ?
  233. _drawRect_mem_copy    dw    0
  234.             dw    ?
  235. _drawRect_mem_and    dw    0
  236.             dw    ?
  237. _drawRect_mem_not    dw    0
  238.             dw    ?
  239. _drawRect_mem_or    dw    0
  240.             dw    ?
  241. _drawRect_mem_xor    dw    0
  242.             dw    ?
  243. _filledRect_scr_copy    dw    filledRect        ; filledRect
  244.             dw    ?
  245. _filledRect_scr_and    dw      0
  246.             dw    ?
  247. _filledRect_scr_not    dw      0
  248.             dw    ?
  249. _filledRect_scr_or    dw      0
  250.             dw    ?
  251. _filledRect_scr_xor    dw    0
  252.             dw    ?
  253. _filledRect_mem_copy    dw    0
  254.             dw    ?
  255. _filledRect_mem_and    dw    0
  256.             dw    ?
  257. _filledRect_mem_not    dw    0
  258.             dw    ?
  259. _filledRect_mem_or    dw    0
  260.             dw    ?
  261. _filledRect_mem_xor    dw    0
  262.             dw    ?
  263. _clearGraphics_scr_copy    dw    clearGraphics        ; clearGraphics
  264.             dw    ?
  265. _clearGraphics_scr_and    dw      0
  266.             dw    ?
  267. _clearGraphics_scr_not    dw      0
  268.             dw    ?
  269. _clearGraphics_scr_or    dw      0
  270.             dw    ?
  271. _clearGraphics_scr_xor    dw    0
  272.             dw    ?
  273. _clearGraphics_mem_copy    dw    0
  274.             dw    ?
  275. _clearGraphics_mem_and    dw    0
  276.             dw    ?
  277. _clearGraphics_mem_not    dw    0
  278.             dw    ?
  279. _clearGraphics_mem_or    dw    0
  280.             dw    ?
  281. _clearGraphics_mem_xor    dw    0
  282.             dw    ?
  283. _ellipse_scr_copy    dw    0            ; ellipse
  284.             dw    ?
  285. _ellipse_scr_and    dw    0
  286.             dw    ?
  287. _ellipse_scr_not    dw    0
  288.             dw    ?
  289. _ellipse_scr_or        dw    0
  290.             dw    ?
  291. _ellipse_scr_xor    dw    0
  292.             dw    ?
  293. _ellipse_mem_copy    dw    0
  294.             dw    ?
  295. _ellipse_mem_and    dw    0
  296.             dw    ?
  297. _ellipse_mem_not    dw    0
  298.             dw    ?
  299. _ellipse_mem_or        dw    0
  300.             dw    ?
  301. _ellipse_mem_xor    dw    0
  302.             dw    ?
  303. _filledEllipse_scr_copy    dw    0            ; filledEllipse
  304.             dw    ?
  305. _filledEllipse_scr_and    dw    0
  306.             dw    ?
  307. _filledEllipse_scr_not    dw    0
  308.             dw    ?
  309. _filledEllipse_scr_or    dw    0
  310.             dw    ?
  311. _filledEllipse_scr_xor    dw    0
  312.             dw    ?
  313. _filledEllipse_mem_copy    dw    0
  314.             dw    ?
  315. _filledEllipse_mem_and    dw    0
  316.             dw    ?
  317. _filledEllipse_mem_not    dw    0
  318.             dw    ?
  319. _filledEllipse_mem_or    dw    0
  320.             dw    ?
  321. _filledEllipse_mem_xor    dw    0
  322.             dw    ?
  323. _circle_scr_copy    dw    0            ; circle
  324.             dw    ?
  325. _circle_scr_and        dw    0
  326.             dw    ?
  327. _circle_scr_not        dw    0
  328.             dw    ?
  329. _circle_scr_or        dw    0
  330.             dw    ?
  331. _circle_scr_xor        dw    0
  332.             dw    ?
  333. _circle_mem_copy    dw    0
  334.             dw    ?
  335. _circle_mem_and        dw    0
  336.             dw    ?
  337. _circle_mem_not        dw    0
  338.             dw    ?
  339. _circle_mem_or        dw    0
  340.             dw    ?
  341. _circle_mem_xor        dw    0
  342.             dw    ?
  343. _filledCircle_scr_copy    dw    0            ; filledCircle
  344.             dw    ?
  345. _filledCircle_scr_and    dw    0
  346.             dw    ?
  347. _filledCircle_scr_not    dw    0
  348.             dw    ?
  349. _filledCircle_scr_or    dw    0
  350.             dw    ?
  351. _filledCircle_scr_xor    dw    0
  352.             dw    ?
  353. _filledCircle_mem_copy    dw    0
  354.             dw    ?
  355. _filledCircle_mem_and    dw    0
  356.             dw    ?
  357. _filledCircle_mem_not    dw    0
  358.             dw    ?
  359. _filledCircle_mem_or    dw    0
  360.             dw    ?
  361. _filledCircle_mem_xor    dw    0
  362.             dw    ?
  363. _fillRegion_scr_copy    dw    0            ; fillRegion
  364.             dw    ?
  365. _fillRegion_scr_and    dw    0
  366.             dw    ?
  367. _fillRegion_scr_not    dw    0
  368.             dw    ?
  369. _fillRegion_scr_or    dw    0
  370.             dw    ?
  371. _fillRegion_scr_xor    dw    0
  372.             dw    ?
  373. _fillRegion_mem_copy    dw    0
  374.             dw    ?
  375. _fillRegion_mem_and    dw    0
  376.             dw    ?
  377. _fillRegion_mem_not    dw    0
  378.             dw    ?
  379. _fillRegion_mem_or    dw    0
  380.             dw    ?
  381. _fillRegion_mem_xor    dw    0
  382.             dw    ?
  383. _fillLine_scr_copy    dw    horizLine_scr_copy    ; fillLine
  384.             dw    ?
  385. _fillLine_scr_and    dw      0
  386.             dw    ?
  387. _fillLine_scr_not    dw      0
  388.             dw    ?
  389. _fillLine_scr_or    dw      0
  390.             dw    ?
  391. _fillLine_scr_xor    dw    0
  392.             dw    ?
  393. _fillLine_mem_copy    dw    horizLine_mem_copy
  394.             dw    ?
  395. _fillLine_mem_and    dw      0
  396.             dw    ?
  397. _fillLine_mem_not    dw      0
  398.             dw    ?
  399. _fillLine_mem_or    dw      0
  400.             dw    ?
  401. _fillLine_mem_xor    dw    0
  402.             dw    ?
  403. ;*** Mode information
  404. scrnMaxX        dw    319    ; physical dimensions
  405. scrnMaxY        dw    199
  406. maxColour        dw    255    ; maximum colour number
  407. xRatio                   dw    8    ; aspect ratio 8:5 (320:200 in
  408. yRatio            dw    5    ;   lowest terms)
  409. bitsPerPixel        dw    8    ; 8 bits per pixel
  410. inMaxX            dw    319    ; current input screen dimensions
  411. inMaxY            dw    199
  412. outMaxX            dw    319    ; current output screen dimensions
  413. outMaxY            dw    199
  414. inScreenWide        dw    ?    ; needed only for virtual screens
  415. outScreenWide        dw    ?
  416. ;*** Viewport information
  417. inViewportULX        dw    0
  418. inViewportULY        dw    0
  419. inViewportLRX        dw    319
  420. inViewportLRY        dw    199
  421. outViewportULX        dw    0
  422. outViewportULY        dw    0
  423. outViewportLRX        dw    319
  424. outViewportLRY        dw    199
  425. ;*** Paging information
  426. pagingSupported        dw    ?    ; not implemented yet
  427. curPage            dw    ?    ; not implemented yet
  428. maxPage            dw    ?    ; not implemented yet
  429. ;*** Force (image width MOD imageWideAdjust) = 0.
  430. imageWideAdjust        dw    ?    ; not implemented yet
  431. ;*** Current and screen addresses
  432.     LABEL    inAddr    DWORD        ; current input address
  433. inOff    dw    0
  434. inSeg    dw    0A000h
  435.     LABEL    outAddr    DWORD        ; current output address
  436. outOff    dw    0
  437. outSeg    dw    0A000h
  438.     LABEL    scrAddr    DWORD        ; screen address
  439. scrOff    dw    0
  440. scrSeg    dw    0A000h
  441. ;*** Copyright string
  442.     db    'The Graphics Engine -- Copyright (c) 1993 by Matthew Hildebrand'
  443.  
  444.  
  445. inited        db    0               ; already initialized flag
  446. tempPalette    db      768    DUP(?)    ; for palette data
  447. lineOffs    dw    200    DUP(?)    ; line start offset table
  448.  
  449.  
  450. ;*****
  451. ;***** initGraphics
  452. ;*****
  453.  
  454. PROC    C    initGraphics
  455.   cmp    [inited],0
  456.   je    @@L1                ; skip if already done
  457.  
  458.   mov    ax,0013h            ; short initialization:
  459.   int    10h                ; turn on graphics and leave
  460.   mov    ax,1
  461.   retf
  462.  
  463.     @@L1:
  464.   push    di                ; first initialization
  465.   mov    [inited],1
  466.  
  467.   mov    ax,1200h            ; enable default palette loading
  468.   mov    bl,31h
  469.   int    10h
  470.   mov    ax,0013h            ; turn on 320x200x256
  471.   int    10h
  472.  
  473.   mov    di,OFFSET lineOffs        ; set up line start offset table
  474.   mov    ax,cs
  475.   mov    es,ax
  476.   mov    cx,200
  477.   xor    bx,bx
  478.   cld
  479.     @@LLoop:
  480.   mov    ax,320
  481.   mul    bx
  482.   inc    bx
  483.   stosw
  484.   loop    @@LLoop
  485.  
  486.   mov    ax,1                ; return success flag
  487.   pop    di
  488.   retf
  489. ENDP
  490.  
  491.  
  492. ;*****
  493. ;***** putImage
  494. ;*****
  495.  
  496. PROC    C    putImage
  497.     ARG    x:WORD,y:WORD,image:DATAPTR
  498.         LOCAL    @@destAdd:WORD,@@srcAdd:WORD,@@xSize:WORD
  499.   push    ds si di
  500.  
  501.   mov    [@@destAdd],320
  502.   mov    [@@srcAdd],0
  503.  
  504.   lds    si,[image]
  505.   les    di,[outAddr]
  506.   cld
  507.  
  508.   lodsw                    ; xsize
  509.   or    ax,ax
  510.   jz    @@Exit
  511.   mov    cx,ax
  512.   mov    [@@xSize],cx
  513.   lodsw                    ; ysize
  514.   or    ax,ax
  515.   jz    @@Exit
  516.   mov    dx,ax
  517.  
  518.   mov    ax,[x]
  519.   cmp    ax,[outViewportLRX]        ; check x <= OUTVIEWPORTLRX
  520.   jg    @@Exit
  521.   cmp    ax,[outViewportULX]        ; check x >= OUTVIEWPORTULX
  522.   jl    @@xLessThanMin
  523.  
  524.     @@checkxMax:
  525.   mov    ax,[x]
  526.   add    ax,cx            ; right edge of image
  527.   cmp    ax,[outViewportLRX]
  528.   jg    @@truncateRightImage    ; truncate if necessary
  529.  
  530.       @@checkyMin:
  531.   mov    ax,[y]
  532.   cmp    ax,[outViewportLRY]        ; check y <= OUTVIEWPORTLRY
  533.   jg    @@Exit
  534.   cmp    ax,[outViewportULY]        ; check y >= OUTVIEWPORTULY
  535.   jl    @@yLessThanMin
  536.  
  537.       @@checkyMax:
  538.   mov    ax,[y]
  539.   add    ax,dx            ; bottom of image
  540.   cmp    ax,[outViewportLRY]
  541.   jg    @@truncateBottomImage    ; truncate if necessary
  542.  
  543.   jmp    short    @@drawImage    ; jump to draw logic
  544.  
  545.     @@xLessThanMin:            ; clip x to 0
  546.   mov    bx,[outViewportULX]
  547.   mov    [x],bx
  548.   sub    bx,ax
  549.   add    si,bx
  550.   sub    cx,bx
  551.   cmp    cx,0
  552.   jle    @@Exit            ; quit if offscreen
  553.   add    [@@srcAdd],bx
  554.   jmp    short    @@checkxMax
  555.  
  556.     @@Exit:                ; quit putImage()
  557.   pop    di si ds
  558.   leave
  559.   retf
  560.  
  561.     @@truncateRightImage:        ; truncate the excess of right edge
  562.   sub    ax,[outViewportLRX]    ; ax=right edge from before
  563.   dec    ax
  564.   sub    cx,ax
  565.   add    [@@srcAdd],ax
  566.   jmp    short    @@checkyMin
  567.  
  568.       @@yLessThanMin:            ; clip y to OUTVIEWPORTULY
  569.   mov    bx,[outViewportULY]
  570.   mov    [y],bx
  571.   sub    bx,ax
  572.   sub    dx,bx
  573.   cmp    dx,0
  574.   jle    @@Exit            ; quit if offscreen
  575.   push    dx cx
  576.   mov    ax,bx
  577.   mov    cx,[@@xSize]
  578.   mul    cx
  579.   pop    cx dx
  580.   add    si,ax
  581.   jmp    short    @@checkyMax
  582.  
  583.     @@truncateBottomImage:        ; clip y to OUTVIEWPORTLRY
  584.   sub    ax,[outViewportLRY]
  585.   dec    ax
  586.   sub    dx,ax
  587.   cmp    dx,0            ; quit if no lines left
  588.   jle    @@Exit            ; fall through to @@drawImage
  589.  
  590.       @@drawImage:            ; label for @@yGreaterThanMax jmp
  591.   push    dx                ; calculate pixel address
  592.   mov    dx,[x]
  593.   mov    ax,[y]
  594.   xchg    ah,al            ; ax=256*y
  595.   add    dx,ax            ; dx=256*y+x
  596.   shr    ax,2            ; ax=64*y
  597.   add    dx,ax            ; dx=320*y+x
  598.   mov    di,dx
  599.   pop    dx
  600.  
  601.   mov    ax,[@@destAdd]
  602.   sub    ax,cx                ; update destAdd
  603.  
  604.   shr    cx,1
  605.   jc    @@LoddNum
  606.   mov    bx,cx                ; MOVSW to be used
  607.   jmp    short    @@LEven2
  608.       @@LEven1:
  609.   add    si,[@@srcAdd]
  610.   add    di,ax            ; destAdd
  611.   mov    cx,bx
  612.       @@LEven2:
  613.   rep    movsw
  614.   dec    dx
  615.   jnz    @@LEven1
  616.   jmp    short    @@Exit
  617.  
  618.     @@LoddNum:            ; MOVSW + MOVSB to be used
  619.   mov    bx,cx                ; preserve xsize
  620.   jmp    short    @@LOdd2            ; only first iteration
  621.     @@LOdd1:            ; copy the bitmap
  622.   add    si,[@@srcAdd]
  623.   add    di,ax            ; destAdd
  624.   mov    cx,bx
  625.       @@LOdd2:
  626.   rep    movsw
  627.   movsb
  628.   dec    dx
  629.   jnz    @@LOdd1
  630.   jmp    @@Exit
  631. ENDP
  632.  
  633.  
  634. ;*****
  635. ;***** putImageInv
  636. ;*****
  637.  
  638. PROC    C    putImageInv
  639.     ARG    x:WORD,y:WORD,image:DATAPTR
  640.         LOCAL    @@destAdd:WORD,@@srcAdd:WORD,@@xSize:WORD
  641.   push    ds si di
  642.  
  643.   mov    [@@destAdd],320
  644.   mov    [@@srcAdd],0
  645.  
  646.   lds    si,[image]
  647.   les    di,[outAddr]
  648.   cld
  649.  
  650.   lodsw                    ; xsize
  651.   or    ax,ax
  652.   jz    @@Exit
  653.   mov    cx,ax
  654.   mov    [@@xSize],cx
  655.   lodsw                    ; ysize
  656.   or    ax,ax
  657.   jz    @@Exit
  658.   mov    dx,ax
  659.  
  660.   mov    ax,[x]
  661.   cmp    ax,[outViewportLRX]        ; check x <= OUTVIEWPORTLRX
  662.   jg    @@Exit
  663.   cmp    ax,[outViewportULX]        ; check x >= OUTVIEWPORTULX
  664.   jl    @@xLessThanMin
  665.  
  666.     @@checkxMax:
  667.   mov    ax,[x]
  668.   add    ax,cx            ; right edge of image
  669.   cmp    ax,[outViewportLRX]
  670.   jg    @@truncateRightImage    ; truncate if necessary
  671.  
  672.       @@checkyMin:
  673.   mov    ax,[y]
  674.   cmp    ax,[outViewportLRY]        ; check y <= OUTVIEWPORTLRY
  675.   jg    @@Exit
  676.   cmp    ax,[outViewportULY]        ; check y >= OUTVIEWPORTULY
  677.   jl    @@yLessThanMin
  678.  
  679.       @@checkyMax:
  680.   mov    ax,[y]
  681.   add    ax,dx            ; bottom of image
  682.   cmp    ax,[outViewportLRY]
  683.   jg    @@truncateBottomImage    ; truncate if necessary
  684.  
  685.   jmp    short    @@drawImage    ; jump to draw logic
  686.  
  687.     @@xLessThanMin:            ; clip x to 0
  688.   mov    bx,[outViewportULX]
  689.   mov    [x],bx
  690.   sub    bx,ax
  691.   add    si,bx
  692.   sub    cx,bx
  693.   cmp    cx,0
  694.   jle    @@Exit            ; quit if offscreen
  695.   add    [@@srcAdd],bx
  696.   jmp    short    @@checkxMax
  697.  
  698.     @@Exit:                ; quit putImage()
  699.   pop    di si ds
  700.   leave
  701.   retf
  702.  
  703.     @@truncateRightImage:        ; truncate the excess of right edge
  704.   sub    ax,[outViewportLRX]    ; ax=right edge from before
  705.   dec    ax
  706.   sub    cx,ax
  707.   add    [@@srcAdd],ax
  708.   jmp    short    @@checkyMin
  709.  
  710.       @@yLessThanMin:            ; clip y to OUTVIEWPORTULY
  711.   mov    bx,[outViewportULY]
  712.   mov    [y],bx
  713.   sub    bx,ax
  714.   sub    dx,bx
  715.   cmp    dx,0
  716.   jle    @@Exit            ; quit if offscreen
  717.   push    dx cx
  718.   mov    ax,bx
  719.   mov    cx,[@@xSize]
  720.   mul    cx
  721.   pop    cx dx
  722.   add    si,ax
  723.   jmp    short    @@checkyMax
  724.  
  725.     @@truncateBottomImage:        ; clip y to OUTVIEWPORTLRY
  726.   sub    ax,[outViewportLRY]
  727.   dec    ax
  728.   sub    dx,ax
  729.   cmp    dx,0            ; quit if no lines left
  730.   jle    @@Exit            ; fall through to @@drawImage
  731.  
  732.      @@drawImage:            ; label for @@yGreaterThanMax jmp
  733. ; calculate the pixel address
  734.   push    dx
  735.   mov    dx,[x]
  736.   mov    ax,[y]
  737.   xchg    ah,al            ; ax=256*y
  738.   add    dx,ax            ; dx=256*y+x
  739.   shr    ax,2            ; ax=64*y
  740.   add    dx,ax            ; dx=320*y+x
  741.   mov    di,dx
  742.   pop    dx
  743.  
  744.   sub    [@@destAdd],cx            ; update destAdd
  745.   mov    bx,cx
  746.   jmp    short    @@xLoop
  747.     @@yLoop:
  748.   add    di,[@@destAdd]
  749.   add    si,[@@srcAdd]
  750.   mov    cx,bx
  751.  
  752.       @@xLoop:
  753.   lodsb
  754.   or    al,al
  755.   jz    @@Invisible
  756.   stosb
  757.   loop    @@xLoop
  758.   dec    dx
  759.   jnz    @@yLoop
  760.   jmp    short    @@Exit
  761.  
  762.     @@Invisible:
  763.   inc    di
  764.   loop    @@xLoop
  765.  
  766.   dec    dx
  767.   jnz    @@yLoop
  768.   jmp    short    @@Exit
  769. ENDP
  770.  
  771.  
  772. ;*****
  773. ;***** getImage
  774. ;*****
  775.  
  776. PROC    C    getImage_scr
  777.     ARG    x1:WORD,y1:WORD,x2:WORD,y2:WORD,image:DATAPTR
  778.   push    ds si di
  779.  
  780.   mov    bx,[inViewportULX]        ; preload for speed
  781.   mov    cx,[inViewportLRX]
  782.  
  783.   mov    ax,[x1]                ; clip x1
  784.   cmp    ax,bx
  785.   jge    @@L1b
  786.   mov    [x1],bx
  787.   jmp    short    @@L2a
  788.       @@L1b:
  789.   cmp    ax,cx
  790.   jle    @@L2a
  791.   mov    [x1],cx
  792.  
  793.       @@L2a:
  794.   mov    ax,[x2]                ; clip x2
  795.   cmp    ax,bx
  796.   jge    @@L2b
  797.   mov    [x2],bx
  798.   jmp    short  @@L3a
  799.       @@L2b:
  800.   cmp    ax,cx
  801.   jle    @@L3a
  802.   mov    [x2],cx
  803.  
  804.       @@L3a:
  805.   mov    bx,[inViewportULY]        ; preload for speed
  806.   mov    cx,[inViewportLRY]
  807.  
  808.   mov    ax,[y1]                ; clip y1
  809.   cmp   ax,bx
  810.   jge    @@L3b
  811.   mov    [y1],bx
  812.   jmp    short    @@L4a
  813.       @@L3b:
  814.   cmp    ax,cx
  815.   jle    @@L4a
  816.   mov    [y1],cx
  817.  
  818.       @@L4a:
  819.   mov    ax,[y2]                ; clip y2
  820.   cmp    ax,bx
  821.   jge    @@L4b
  822.   mov    [y2],bx
  823.   jmp    short    @@L5
  824.       @@L4b:
  825.   cmp    ax,cx
  826.   jle    @@L5
  827.   mov    [y2],cx
  828.  
  829.       @@L5:
  830.   mov    ax,[x2]                ; make sure x2>=x1
  831.   cmp    ax,[x1]
  832.   jge    @@L6
  833.   mov    dx,[x1]
  834.   mov    [x2],dx
  835.   mov    [x1],ax
  836.     @@L6:
  837.   mov    ax,[y2]                ; make sure y2>=y1
  838.   cmp    ax,[y1]
  839.   jge    @@L7
  840.   mov    dx,[y1]
  841.   mov    [y2],dx
  842.   mov    [y1],ax
  843.  
  844.     @@L7:
  845.   cld
  846.   lds    si,[inAddr]            ; set up DS:SI
  847.   mov    bx,[y1]
  848.   shl    bx,1
  849.   add    si,[cs:lineOffs+bx]
  850.   add    si,[x1]
  851.  
  852.   les    di,[image]            ; set up ES:DI
  853.   mov    ax,[x2]
  854.   sub    ax,[x1]
  855.   inc    ax
  856.   push    ax
  857.   stosw                    ; store image width
  858.   mov    ax,[y2]
  859.   sub    ax,[y1]
  860.   inc    ax
  861.   stosw                    ; store image depth
  862.  
  863.   mov    ax,[x2]                ; calculate srcAdd
  864.   sub    ax,[x1]
  865.   mov    dx,319
  866.   sub    dx,ax
  867.   push    dx                ; save srcAdd for later
  868.  
  869.   mov    ax,[y2]                ; y loop counter
  870.   sub    ax,[y1]
  871.   mov    dx,ax
  872.   inc    dx
  873.  
  874.   pop    ax
  875.   pop    cx                ; pop pushed width (x loop counter)
  876.  
  877.   shr    cx,1
  878.   jc    @@LOdd
  879.   mov    bx,cx                ; MOVSW to be used
  880.   jmp    short    @@LoopEvenEntry
  881.     @@LoopEven:
  882.   add    si,ax
  883.   mov    cx,bx
  884.     @@LoopEvenEntry:
  885.   rep    movsw
  886.   dec    dx
  887.   jnz    @@LoopEven
  888.   jmp    short    @@LExit
  889.  
  890.     @@LOdd:                ; MOVSW + MOVSB to be used
  891.   mov    bx,cx
  892.   jmp    short    @@LoopOddEntry
  893.     @@LoopOdd:
  894.   add    si,ax            ; srcAdd
  895.   mov    cx,bx
  896.     @@LoopOddEntry:
  897.   rep    movsw
  898.   movsb
  899.   dec    dx
  900.   jnz    @@LoopOdd
  901.  
  902.     @@LExit:
  903.   pop    di si ds
  904.   leave
  905.   retf
  906. ENDP
  907.  
  908.  
  909. ;*****
  910. ;***** putLine
  911. ;*****
  912.  
  913. PROC    C    putLine_scr_copy
  914.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  915.   push    ds si di
  916.   cld
  917.   les    di,[outAddr]
  918.   lds    si,[buf]
  919.  
  920.   mov    bx,[lineNum]
  921.   shl    bx,1
  922.   add    di,[cs:lineOffs+bx]
  923.   add    di,[xOff]
  924.   mov    cx,[lineLen]
  925.  
  926.   shr    cx,1
  927.   rep    movsw
  928.   jc    @@L1
  929.   pop    di si ds
  930.   leave
  931.   retf
  932.  
  933.     @@L1:
  934.   movsb
  935.   pop    di si ds
  936.   leave
  937.   retf
  938. ENDP
  939.  
  940. PROC    C    putLine_mem_copy
  941.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  942.   push    ds si di            ; save these registers
  943.  
  944.   xor    eax,eax                ; clear EAX
  945.   xor    edx,edx                ; clear EDX
  946.   xor    edi,edi                ; clear EDI
  947.  
  948.   les    di,[outAddr]            ; load output address
  949.   mov    ax,[y]
  950.   mov    dx,[outScreenWide]
  951.   mul    edx                    ; EDX:EAX = offset - EDI - x
  952.   add    edi,eax                ; EDI = offset - x
  953.   mov    dx,[xOff]
  954.   add    edi,edx                ; EDI = offset
  955.   mov    edx,edi                ; EDX = offset
  956.   shr    edx,4                ; EDX = # of paragraphs (segments)
  957.   add    dx,[outSeg]            ; DX = new segment
  958.   mov    es,dx                ; ES = new segment
  959.   and    di,0000000000001111b             ; DI = offset within new segment
  960.  
  961.   lds    si,[buf]            ; load input address
  962.   mov    dx,si                ; DX = offset
  963.   shr    dx,4                ; DX = # of paragraphs (segments)
  964.   mov    ax,ds                ; AX = DS
  965.   add    ax,dx                ; AX = new DS
  966.   mov    ds,ax                ; DS = new DS
  967.   and    si,0000000000001111b        ; SI = offset within new segment
  968.  
  969.   cld
  970.   mov    cx,[lineLen]            ; CX = line length
  971.   mov    dx,cx                ; DX = line length
  972.   shr    cx,2                ; CX = line length in dwords
  973.   rep    movsd                     ; move the dwords if necessary
  974.   mov    cx,dx                ; CX = line length in bytes
  975.   and    cx,0000000000000011b        ; CX = any residual bytes
  976.   rep    movsb                ; move the bytes if necessary
  977.  
  978.   pop    di si ds            ; restore registers
  979.   leave                    ; clean up
  980.   retf                    ; return
  981. ENDP
  982.  
  983.  
  984. ;*****
  985. ;***** getLine
  986. ;*****
  987.  
  988. PROC    C    getLine_scr
  989.     ARG    lineNum:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  990.   cld
  991.   push    ds si di
  992.   les    di,[buf]
  993.   lds    si,[inAddr]
  994.  
  995.   mov    bx,[lineNum]
  996.   shl    bx,1
  997.   add    si,[cs:lineOffs+bx]
  998.   add    si,[xOff]
  999.   mov    cx,[lineLen]
  1000.  
  1001.   shr    cx,1
  1002.   rep    movsw
  1003.   jc    @@L1
  1004.   pop    di si ds
  1005.   leave
  1006.   retf
  1007.  
  1008.     @@L1:
  1009.   movsb
  1010.   pop    di si ds
  1011.   leave
  1012.   retf
  1013. ENDP
  1014.  
  1015. PROC    C    getLine_mem
  1016.     ARG    y:WORD, xOff:WORD, lineLen:WORD, buf:DATAPTR
  1017.   push    ds si di            ; save these registers
  1018.  
  1019.   xor    eax,eax                ; clear EAX
  1020.   xor    edx,edx                ; clear EDX
  1021.   xor    esi,esi                ; clear ESI
  1022.  
  1023.   les    si,[inAddr]            ; load input address
  1024.   mov    ax,[y]
  1025.   mov    dx,[inScreenWide]
  1026.   mul    edx                    ; EDX:EAX = offset - ESI - x
  1027.   add    esi,eax                ; ESI = offset - x
  1028.   mov    dx,[xOff]
  1029.   add    esi,edx                ; ESI = offset
  1030.   mov    edx,esi                ; EDX = offset
  1031.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1032.   add    dx,[inSeg]            ; DX = new segment
  1033.   mov    ds,dx                ; ES = new segment
  1034.   and    si,0000000000001111b             ; SI = offset within new segment
  1035.  
  1036.   les    di,[buf]            ; load output address
  1037.   mov    dx,di                ; DX = offset
  1038.   shr    dx,4                ; DX = # of paragraphs (segments)
  1039.   mov    ax,es                ; AX = ES
  1040.   add    ax,dx                ; AX = new ES
  1041.   mov    es,ax                ; ES = new ES
  1042.   and    di,0000000000001111b        ; DI = offset within new segment
  1043.  
  1044.   cld
  1045.   mov    cx,[lineLen]            ; CX = line length
  1046.   mov    dx,cx                ; DX = line length
  1047.   shr    cx,2                ; CX = line length in dwords
  1048.   rep    movsd                     ; move the dwords if necessary
  1049.   mov    cx,dx                ; CX = line length in bytes
  1050.   and    cx,0000000000000011b        ; CX = any residual bytes
  1051.   rep    movsb                ; move the bytes if necessary
  1052.  
  1053.   pop    di si ds            ; restore registers
  1054.   leave                    ; clean up
  1055.   retf                    ; return
  1056. ENDP
  1057.  
  1058.  
  1059. ;*****
  1060. ;***** putPixel
  1061. ;*****
  1062.  
  1063. ; Copy a pixel to the screen
  1064. PROC    C    putPixel_scr_copy
  1065.     ARG    x:WORD,y:WORD,colour:BYTE
  1066.   mov   ax,0A000h
  1067.   mov    es,ax
  1068.   mov    bx,[y]
  1069.   shl    bx,1
  1070.   mov    bx,[cs:lineOffs+bx]
  1071.   add    bx,[x]
  1072.   mov    al,[colour]
  1073.   mov    [es:bx],al
  1074.   leave
  1075.   retf
  1076. ENDP
  1077.  
  1078. ; AND a pixel to the screen
  1079. PROC    C    putPixel_scr_and
  1080.     ARG    x:WORD,y:WORD,colour:BYTE
  1081.   mov   ax,0A000h
  1082.   mov    es,ax
  1083.   mov    bx,[y]
  1084.   shl    bx,1
  1085.   mov    bx,[cs:lineOffs+bx]
  1086.   add    bx,[x]
  1087.   mov    al,[es:bx]
  1088.   and    al,[colour]
  1089.   mov    [es:bx],al
  1090.   leave
  1091.   retf
  1092. ENDP
  1093.  
  1094. ; NOT a pixel to the screen
  1095. PROC    C    putPixel_scr_not
  1096.     ARG    x:WORD,y:WORD,colour:BYTE
  1097.   mov   ax,0A000h
  1098.   mov    es,ax
  1099.   mov    bx,[y]
  1100.   shl    bx,1
  1101.   mov    bx,[cs:lineOffs+bx]
  1102.   add    bx,[x]
  1103.   mov    al,[colour]
  1104.   not    al
  1105.   mov    [es:bx],al
  1106.   leave
  1107.   retf
  1108. ENDP
  1109.  
  1110. ; OR a pixel to the screen
  1111. PROC    C    putPixel_scr_or
  1112.     ARG    x:WORD,y:WORD,colour:BYTE
  1113.   mov   ax,0A000h
  1114.   mov    es,ax
  1115.   mov    bx,[y]
  1116.   shl    bx,1
  1117.   mov    bx,[cs:lineOffs+bx]
  1118.   add    bx,[x]
  1119.   mov    al,[es:bx]
  1120.   or    al,[colour]
  1121.   mov    [es:bx],al
  1122.   leave
  1123.   retf
  1124. ENDP
  1125.  
  1126. ; XOR a pixel to the screen
  1127. PROC    C    putPixel_scr_xor
  1128.     ARG    x:WORD,y:WORD,colour:BYTE
  1129.   mov   ax,0A000h
  1130.   mov    es,ax
  1131.   mov    bx,[y]
  1132.   shl    bx,1
  1133.   mov    bx,[cs:lineOffs+bx]
  1134.   add    bx,[x]
  1135.   mov    al,[es:bx]
  1136.   xor    al,[colour]
  1137.   mov    [es:bx],al
  1138.   leave
  1139.   retf
  1140. ENDP
  1141.  
  1142. ; Copy a pixel to memory
  1143. PROC    C    putPixel_mem_copy
  1144.     ARG    x:WORD,y:WORD,colour:BYTE
  1145.   xor    eax,eax                ; clear EAX
  1146.   xor    ebx,ebx                ; clear EBX
  1147.   xor    edx,edx                ; clear EDX
  1148.  
  1149.   les    bx,[outAddr]            ; load output address
  1150.   mov    ax,[y]
  1151.   mov    dx,[outScreenWide]
  1152.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1153.   add    ebx,eax                ; EBX = offset - x
  1154.   mov    dx,[x]
  1155.   add    ebx,edx                ; EBX = offset
  1156.  
  1157.   mov    edx,ebx                ; EDX = offset
  1158.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1159.   add    dx,[outSeg]            ; DX = new segment
  1160.   mov    es,dx                ; ES = new segment
  1161.   and    bx,0000000000001111b             ; BX = offset within new segment
  1162.  
  1163.   mov    al,[colour]            ; colour in AL
  1164.   mov    [es:bx],al            ; store pixel
  1165.   leave                    ; clean up
  1166.   retf                    ; return
  1167. ENDP
  1168.  
  1169. ; AND a pixel to memory
  1170. PROC    C    putPixel_mem_and
  1171.     ARG    x:WORD,y:WORD,colour:BYTE
  1172.   xor    eax,eax                ; clear EAX
  1173.   xor    ebx,ebx                ; clear EBX
  1174.   xor    edx,edx                ; clear EDX
  1175.  
  1176.   les    bx,[outAddr]            ; load output address
  1177.   mov    ax,[y]
  1178.   mov    dx,[outScreenWide]
  1179.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1180.   add    ebx,eax                ; EBX = offset - x
  1181.   mov    dx,[x]
  1182.   add    ebx,edx                ; EBX = offset
  1183.  
  1184.   mov    edx,ebx                ; EDX = offset
  1185.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1186.   add    dx,[outSeg]            ; DX = new segment
  1187.   mov    es,dx                ; ES = new segment
  1188.   and    bx,0000000000001111b             ; BX = offset within new segment
  1189.  
  1190.   mov    al,[colour]            ; colour in AL
  1191.   and    [es:bx],al            ; AND pixel
  1192.   leave                    ; clean up
  1193.   retf                    ; return
  1194. ENDP
  1195.  
  1196. ; NOT a pixel to memory
  1197. PROC    C    putPixel_mem_not
  1198.     ARG    x:WORD,y:WORD,colour:BYTE
  1199.   xor    eax,eax                ; clear EAX
  1200.   xor    ebx,ebx                ; clear EBX
  1201.   xor    edx,edx                ; clear EDX
  1202.  
  1203.   les    bx,[outAddr]            ; load output address
  1204.   mov    ax,[y]
  1205.   mov    dx,[outScreenWide]
  1206.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1207.   add    ebx,eax                ; EBX = offset - x
  1208.   mov    dx,[x]
  1209.   add    ebx,edx                ; EBX = offset
  1210.  
  1211.   mov    edx,ebx                ; EDX = offset
  1212.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1213.   add    dx,[outSeg]            ; DX = new segment
  1214.   mov    es,dx                ; ES = new segment
  1215.   and    bx,0000000000001111b             ; BX = offset within new segment
  1216.  
  1217.   mov    al,[colour]            ; colour in AL
  1218.   not    al                ; NOT it
  1219.   mov    [es:bx],al            ; store NOTed pixel
  1220.   leave                    ; clean up
  1221.   retf                    ; return
  1222. ENDP
  1223.  
  1224. ; OR a pixel to memory
  1225. PROC    C    putPixel_mem_or
  1226.     ARG    x:WORD,y:WORD,colour:BYTE
  1227.   xor    eax,eax                ; clear EAX
  1228.   xor    ebx,ebx                ; clear EBX
  1229.   xor    edx,edx                ; clear EDX
  1230.  
  1231.   les    bx,[outAddr]            ; load output address
  1232.   mov    ax,[y]
  1233.   mov    dx,[outScreenWide]
  1234.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1235.   add    ebx,eax                ; EBX = offset - x
  1236.   mov    dx,[x]
  1237.   add    ebx,edx                ; EBX = offset
  1238.  
  1239.   mov    edx,ebx                ; EDX = offset
  1240.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1241.   add    dx,[outSeg]            ; DX = new segment
  1242.   mov    es,dx                ; ES = new segment
  1243.   and    bx,0000000000001111b             ; BX = offset within new segment
  1244.  
  1245.   mov    al,[colour]            ; colour in AL
  1246.   or    [es:bx],al            ; OR pixel
  1247.   leave                    ; clean up
  1248.   retf                    ; return
  1249. ENDP
  1250.  
  1251. ; XOR a pixel to memory
  1252. PROC    C    putPixel_mem_xor
  1253.     ARG    x:WORD,y:WORD,colour:BYTE
  1254.   xor    eax,eax                ; clear EAX
  1255.   xor    ebx,ebx                ; clear EBX
  1256.   xor    edx,edx                ; clear EDX
  1257.  
  1258.   les    bx,[outAddr]            ; load output address
  1259.   mov    ax,[y]
  1260.   mov    dx,[outScreenWide]
  1261.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1262.   add    ebx,eax                ; EBX = offset - x
  1263.   mov    dx,[x]
  1264.   add    ebx,edx                ; EBX = offset
  1265.  
  1266.   mov    edx,ebx                ; EDX = offset
  1267.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1268.   add    dx,[outSeg]            ; DX = new segment
  1269.   mov    es,dx                ; ES = new segment
  1270.   and    bx,0000000000001111b             ; BX = offset within new segment
  1271.  
  1272.   mov    al,[colour]            ; colour in AL
  1273.   xor    [es:bx],al            ; XOR pixel
  1274.   leave                    ; clean up
  1275.   retf                    ; return
  1276. ENDP
  1277.  
  1278.  
  1279. ;*****
  1280. ;***** getPixel
  1281. ;*****
  1282.  
  1283. ; Get a pixel from the screen
  1284. PROC    C    getPixel_scr
  1285.     ARG    x:WORD,y:WORD
  1286.   mov    ax,0A000h
  1287.   mov    es,ax
  1288.   mov    bx,[y]
  1289.   shl    bx,1
  1290.   mov    bx,[cs:lineOffs+bx]
  1291.   add    bx,[x]
  1292.   mov    al,[es:bx]
  1293.   xor    ah,ah
  1294.   leave
  1295.   retf
  1296. ENDP
  1297.  
  1298. ; Get a pixel from memory
  1299. PROC    C    getPixel_mem
  1300.     ARG    x:WORD,y:WORD
  1301.   xor    eax,eax                ; clear EAX
  1302.   xor    ebx,ebx                ; clear EBX
  1303.   xor    edx,edx                ; clear EDX
  1304.  
  1305.   les    bx,[inAddr]            ; load input address
  1306.   mov    ax,[y]
  1307.   mov    dx,[inScreenWide]
  1308.   mul    edx                    ; EDX:EAX = offset - EBX - x
  1309.   add    ebx,eax                ; EBX = offset - x
  1310.   mov    dx,[x]
  1311.   add    ebx,edx                ; EBX = offset
  1312.  
  1313.   mov    edx,ebx                ; EDX = offset
  1314.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1315.   add    dx,[inSeg]            ; DX = new segment
  1316.   mov    es,dx                ; ES = new segment
  1317.   and    bx,0000000000001111b             ; BX = offset within new segment
  1318.  
  1319.   xor    ax,ax                ; clear AX
  1320.   mov    al,[es:bx]            ; store pixel in AX for return
  1321.   leave                    ; clean up
  1322.   retf                    ; return
  1323. ENDP
  1324.  
  1325.  
  1326. ;*****
  1327. ;***** line
  1328. ;*****
  1329.  
  1330. ; The following line routine is a modified version of code in Richard
  1331. ; Wilton's book "Programmer's Guide to PC and PS/2 Video Systems".
  1332. SCREENSEG    EQU    0A000h
  1333.  
  1334. MACRO    PIXELADDR
  1335.   xchg    ah,al            ; ax=256*y
  1336.   add    bx,ax            ; bx=256*y+x
  1337.   shr    ax,2
  1338.   add    bx,ax            ; bx=320*y+x (+ offset in buffer if needed.)
  1339.   mov    ax,SCREENSEG
  1340.   mov    es,ax            ; es:bx=address of pixel
  1341. ENDM
  1342.  
  1343.     MASM
  1344.  
  1345. ; void line(x1,y1,x2,y2,colour)
  1346. ; int x1,y1,x2,y2;
  1347. ; unsigned char colour;
  1348. ARGx1        EQU    word ptr [bp+6]
  1349. ARGy1        EQU    word ptr [bp+8]
  1350. ARGx2        EQU    word ptr [bp+10]
  1351. ARGy2        EQU    word ptr [bp+12]
  1352. ARGcolour    EQU    byte ptr [bp+14]
  1353. VARincr1    EQU    word ptr [bp-2]
  1354. VARincr2    EQU    word ptr [bp-4]
  1355. VARroutine    EQU    word ptr [bp-6]
  1356. line    PROC    FAR
  1357.     push    bp
  1358.         mov    bp,sp
  1359.         sub    sp,6
  1360.         push    si
  1361.         push    di
  1362.  
  1363. ; check for vertical lines
  1364.     mov    si,320                ; initial y-increment
  1365.         mov    cx,ARGx2
  1366.         sub    cx,ARGx1            ; cx=x2-x1
  1367.         jz    vertLine
  1368.  
  1369. ; force x1 < x2
  1370.     jns    L01                ; jump if x1<x2
  1371.         neg    cx                ; cx=x1-x2
  1372.         mov    bx,ARGx2            ; exchange x1 and x2
  1373.         xchg    bx,ARGx1
  1374.         mov    ARGx2,bx
  1375.         mov    bx,ARGy2            ; exchange y1 and y2
  1376.         xchg    bx,ARGy1
  1377.         mov    ARGy2,bx
  1378.  
  1379. ; calculate dy=abs(y2-y1)
  1380. L01:    mov    bx,ARGy2
  1381.         sub    bx,ARGy1            ; bx=y2-y1
  1382.     jz    @@horizLine
  1383.     jns    L03                ; jump if slope is positive
  1384.     neg    bx                ; bx=y1-y2
  1385.         neg    si                ; negate y-increment
  1386.  
  1387. ; select appropriate routine for slope of line
  1388. L03:    push    si
  1389.     mov    VARroutine,offset loSlopeLine
  1390.         cmp    bx,cx
  1391.         jle    L04                ; jump if dy<=dx (slope <=1)
  1392.         mov     VARroutine,offset hiSlopeLine
  1393.         xchg    bx,cx                ; exchange dy and dx
  1394.  
  1395. ; calculate initial decision variable and increments
  1396. L04:    shl    bx,1                ; bx=2*dy
  1397.     mov    VARincr1,bx            ; incr1=2*dy
  1398.         sub    bx,cx
  1399.         mov    si,bx                ; si=d=2*dy-dx
  1400.         sub    bx,cx
  1401.         mov    VARincr2,bx            ; incr2=2*(dy-dx)
  1402.  
  1403. ; calculate first pixel address
  1404.     push    cx
  1405.         mov    ax,ARGy1
  1406.         mov    bx,ARGx1
  1407.         PIXELADDR
  1408.         mov    di,bx
  1409.     pop    cx
  1410.         inc    cx                ; cx=# of pixels to draw
  1411.         pop    bx                ; bx=y-increment
  1412.         jmp    VARroutine            ; jump to appropriate routine
  1413.  
  1414. ; routine for vertical lines
  1415. vertLine:    mov    ax,ARGy1
  1416.         mov    bx,ARGy2
  1417.                 mov    cx,bx
  1418.                 sub    cx,ax            ; cx=dy
  1419.                 jge    L31            ; jump if dy>=0
  1420.                 neg    cx            ; force dy>=0
  1421.                 mov    ax,bx            ; ax=y2
  1422. L31:    inc    cx                ; cx=# of pixels to draw
  1423.     mov    bx,ARGx1            ; bx=x
  1424.     PIXELADDR                ; es:bx
  1425.         mov    di,bx                ; es:di
  1426.         dec    si                ; si=bytes/line-1
  1427.         mov    al,ARGcolour
  1428.  
  1429. L32:    stosb
  1430.     add    di,si                ; next line
  1431.         loop    L32
  1432.         jmp    short    Lexit
  1433.  
  1434. ; routine for horizontal lines (slope=0)
  1435. @@horizLine:    push    cx
  1436.         mov    ax,ARGy1
  1437.                 mov    bx,ARGx1
  1438.                 PIXELADDR            ; es:bx
  1439.                 mov    di,bx            ; es:di
  1440.                 pop    cx
  1441.                 inc    cx            ; cx=# of pixels to draw
  1442.                 mov    al,ARGcolour
  1443.         rep    stosb
  1444.         jmp    short    Lexit
  1445.  
  1446. ; routine for dy<=dx (slope<=1)            ; es:di -> video buffer
  1447.                         ; bx=y-increment
  1448.                                                 ; cx =# of pixels to draw
  1449.                         ; si=decision variable
  1450. loSlopeLine:    mov    al,ARGcolour
  1451.  
  1452. L11:    stosb                    ; put pixel, increment x
  1453.     or    si,si                ; test sign of d
  1454.         jns    L12                ; jump id d>=0
  1455.         add    si,VARincr1            ; d=d+incr1
  1456.         loop    L11
  1457.         jmp    short    Lexit
  1458.  
  1459. L12:    add    si,VARincr2            ; d=d+incr2
  1460.     add    di,bx                ; increment y
  1461.         loop    L11
  1462.         jmp    short    Lexit
  1463.  
  1464. ; routine for dy>dx (slope >1)            ; es:di -> video buffer
  1465.                         ; bx=y-increment
  1466.                         ; cx=# of pixels to draw
  1467.                         ; si=decision variable
  1468. hiSlopeLine:    mov    al,ARGcolour
  1469.  
  1470. L21:    stosb                    ; put pixel, increment x
  1471.     add    di,bx                ; increment y
  1472.  
  1473. L22:    or    si,si                ; test sign of d
  1474.     jns    L23                ; jump if d>=0
  1475.     add    si,VARincr1            ; d=d+incr1
  1476.     dec    di                ; dec x (inc by stosb)
  1477.     loop    L21
  1478.     jmp    short    Lexit
  1479.  
  1480. L23:    add    si,VARincr2            ; d=d+incr2
  1481.     loop    L21
  1482.  
  1483. Lexit:    pop    di
  1484.     pop    si
  1485.     mov    sp,bp
  1486.     pop    bp
  1487.     ret
  1488. line    ENDP
  1489.  
  1490.     IDEAL
  1491.  
  1492.  
  1493. ;*****
  1494. ;***** horizLine
  1495. ;*****
  1496.  
  1497. PROC    C    horizLine_scr_copy
  1498.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1499.   push    di
  1500.  
  1501.   les    di,[outAddr]            ; load output address
  1502.   mov    bx,[y]                ; BX = y-coordinate
  1503.   mov    ax,[x1]                ; CX = # of pixels
  1504.   mov    cx,[x2]
  1505.   sub    cx,ax
  1506.   inc    cx
  1507.  
  1508.   shl    bx,1                ; DI = output address
  1509.   add    di,[cs:lineOffs+bx]
  1510.   add    di,ax
  1511.  
  1512.   mov    al,[colour]            ; AL = colour
  1513.   mov    ah,al                ; AH = colour
  1514.   shr    cx,1                ; store the bytes
  1515.   rep    stosw
  1516.   adc    cx,0
  1517.   rep    stosb
  1518.   pop    di                ; restore DI
  1519.   leave                    ; clean up the stack
  1520.   retf                    ; return
  1521. ENDP
  1522.  
  1523. PROC    C    horizLine_mem_copy
  1524.     ARG    y:WORD, x1:WORD, x2:WORD, colour:BYTE
  1525.   push    edi                ; store EDI
  1526.  
  1527.   xor    eax,eax                ; clear EAX
  1528.   xor    edi,edi                ; clear EDI
  1529.   xor    edx,edx                ; clear EDX
  1530.  
  1531.   les    di,[outAddr]            ; load output address
  1532.   mov    ax,[y]
  1533.   mov    dx,[outScreenWide]
  1534.   mul    edx                    ; EDX:EAX = offset - EDI - x
  1535.   add    edi,eax                ; EDI = offset - x
  1536.   mov    dx,[x1]
  1537.   add    edi,edx                ; EDI = offset
  1538.   mov    edx,edi                ; EDX = offset
  1539.   shr    edx,4                ; EDX = # of paragraphs (segments)
  1540.   add    dx,[outSeg]            ; DX = new segment
  1541.   mov    es,dx                ; ES = new segment
  1542.   and    di,0000000000001111b             ; DI = offset within new segment
  1543.  
  1544.   mov    al,[colour]            ; colour in AL
  1545.   mov    ah,al                ; colour in AH
  1546.   mov    bx,ax
  1547.   shl    eax,16
  1548.   mov    ax,bx                 ; colour in each byte of EAX
  1549.  
  1550.   mov    cx,[x2]
  1551.   sub    cx,[x1]
  1552.   inc    cx                ; CX = line length in pixels
  1553.   mov    dx,cx                ; DX = line length in bytes
  1554.  
  1555.   shr    cx,2                ; CX = line length in dwords
  1556.   rep    stosd                ; store four bytes at a time
  1557.   mov    cx,dx                ; CX = line length in pixels
  1558.   and    cx,0000000000000011b        ; CX = any remaining bytes
  1559.   rep    stosb                ; store the remaining bytes
  1560.  
  1561.   pop    edi                    ; restore EDI
  1562.   leave                    ; clean up
  1563.   retf                    ; return
  1564. ENDP
  1565.  
  1566.  
  1567. ;*****
  1568. ;***** filledRect
  1569. ;*****
  1570.  
  1571. PROC    C    filledRect
  1572.     ARG    x1:WORD, y1:WORD, x2:WORD, y2:WORD, colour:BYTE
  1573.   push    di si
  1574.   les    di,[outAddr]
  1575.  
  1576.   mov    ax,[y1]        ; y coords
  1577.   mov    bx,[y2]
  1578.   cmp    ax,bx
  1579.   jbe    @@L1
  1580.   xchg    ax,bx
  1581.  
  1582.     @@L1:
  1583.   sub    bx,ax                ; ySize in BX
  1584.   inc    bx
  1585.   mov    si,320                ; update DI
  1586.   mul    si
  1587.   add    di,ax
  1588.  
  1589.   mov    dx,[x1]        ; x coords
  1590.   mov    cx,[x2]
  1591.   cmp    dx,cx
  1592.   jbe    @@L2
  1593.   xchg    cx,dx
  1594.  
  1595.     @@L2:
  1596.   add    di,dx
  1597.  
  1598.   sub    cx,dx                ; xSize in CX
  1599.   inc    cx
  1600.  
  1601.   sub    si,cx                ; xAdd in SI
  1602.  
  1603.   mov    al,[colour]            ; colour
  1604.   mov    ah,al
  1605.  
  1606.   cld
  1607.   shr    cx,1
  1608.   mov    dx,cx
  1609.   jc    @@LOddEntry
  1610.   jmp    short    @@LEvenEntry
  1611.  
  1612.     @@LEvenNum:            ; MOVSW to be used
  1613.   add    di,si
  1614.   mov    cx,dx
  1615.     @@LEvenEntry:
  1616.   rep    stosw
  1617.   dec    bx
  1618.   jnz    @@LEvenNum
  1619.  
  1620.   pop   si di
  1621.   leave
  1622.   retf
  1623.  
  1624.     @@LOddNum:
  1625.   add   di,si
  1626.   mov    cx,dx
  1627.     @@LOddEntry:
  1628.   rep    stosw
  1629.   stosb
  1630.   dec    bx
  1631.   jnz    @@LOddNum
  1632.  
  1633.   pop    si di
  1634.   leave
  1635.   retf
  1636. ENDP
  1637.  
  1638.  
  1639. ;*****
  1640. ;***** setPaletteReg
  1641. ;*****
  1642.  
  1643. PROC    C    setPaletteReg
  1644.     ARG    palNum:WORD,red:BYTE,green:BYTE,blue:BYTE
  1645.   mov    bx,[palNum]
  1646.  
  1647.   mov    dh,[red]            ; red
  1648.   shr    dh,2
  1649.   jnc    @@L1
  1650.   cmp    dh,63
  1651.   je    @@L1
  1652.   inc    dh
  1653.  
  1654.     @@L1:
  1655.   mov    ch,[green]            ; green
  1656.   shr    ch,2
  1657.   jnc    @@L2
  1658.   cmp    ch,63
  1659.   je    @@L2
  1660.   inc    ch
  1661.  
  1662.       @@L2:
  1663.   mov    cl,[blue]
  1664.   shr    cl,2
  1665.   jnc    @@L3
  1666.   cmp    cl,63
  1667.   je    @@L3
  1668.   inc    cl
  1669.  
  1670.       @@L3:
  1671.   mov    ax,1010h
  1672.   int    10h
  1673.   leave
  1674.   retf
  1675. ENDP
  1676.  
  1677.  
  1678. ;*****
  1679. ;***** getPaletteReg
  1680. ;*****
  1681.  
  1682. PROC    C    getPaletteReg
  1683.     ARG    palNum:WORD,red:DATAPTR,green:DATAPTR,blue:DATAPTR
  1684.   push    ds si
  1685.   mov    ax,1015h
  1686.   mov    bx,[palNum]
  1687.   int    10h
  1688.   lds    si,[red]
  1689.   shl    dh,2
  1690.   mov    [ds:si],dh
  1691.   lds    si,[green]
  1692.   shl    ch,2
  1693.   mov    [ds:si],ch
  1694.   lds    si,[blue]
  1695.   shl    cl,2
  1696.   mov    [ds:si],cl
  1697.   pop    si ds
  1698.   leave
  1699.   retf
  1700. ENDP
  1701.  
  1702.  
  1703. ;*****
  1704. ;***** setBlockPalette
  1705. ;*****
  1706.  
  1707. PROC    C    setBlockPalette
  1708.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1709.   push    ds si di
  1710.   lds    si,[paletteData]
  1711.   push    cs
  1712.   pop    es
  1713.   mov    di,OFFSET tempPalette
  1714.   mov    cx,[lastReg]
  1715.   inc    cx
  1716.   push    cx
  1717.   cld
  1718.  
  1719.     @@LLoop:
  1720.   lodsb            ; red
  1721.   shr    al,2
  1722.   jnc    @@L1
  1723.   cmp    al,63
  1724.   je    @@L1
  1725.   inc    al
  1726.       @@L1:
  1727.   stosb
  1728.   lodsb            ; green
  1729.   shr    al,2
  1730.   jnc    @@L2
  1731.   cmp    al,63
  1732.   je    @@L2
  1733.   inc    al
  1734.       @@L2:
  1735.   stosb
  1736.   lodsb            ; blue
  1737.   shr    al,2
  1738.   jnc    @@L3
  1739.   cmp    al,63
  1740.   je    @@L3
  1741.   inc    al
  1742.       @@L3:
  1743.   stosb
  1744.   loop    @@LLoop
  1745.  
  1746.   mov    ax,1012h
  1747.   mov    bx,[firstReg]            ; first colour reg
  1748.   pop    cx                ; # of colour regs
  1749.   mov    dx,OFFSET tempPalette        ; ES = CS
  1750.   int    10h
  1751.  
  1752.     @@LExit:
  1753.   pop    di si ds
  1754.   leave
  1755.   retf
  1756. ENDP
  1757.  
  1758.  
  1759. ;*****
  1760. ;***** getBlockPalette
  1761. ;*****
  1762.  
  1763. PROC    C    getBlockPalette
  1764.     ARG    firstReg:WORD,lastReg:WORD,paletteData:DATAPTR
  1765.   push    ds si di
  1766.   mov    ax,1017h
  1767.   mov    bx,[firstReg]
  1768.   mov    cx,[lastReg]
  1769.   inc    cx
  1770.   push    cs
  1771.   pop    es
  1772.   mov    dx,OFFSET tempPalette
  1773.   int    10h
  1774.  
  1775.   les    di,[paletteData]
  1776.   mov    ax,cs
  1777.   mov    ds,ax
  1778.   mov    si,OFFSET tempPalette
  1779.   mov    cx,[lastReg]
  1780.   inc    cx
  1781.   cld
  1782.  
  1783.     @@L1:
  1784.   lodsb
  1785.   shl    al,2
  1786.   stosb        ; red
  1787.   lodsb
  1788.   shl    al,2
  1789.   stosb        ; green
  1790.   lodsb
  1791.   shl    al,2
  1792.   stosb        ; blue
  1793.   loop    @@L1
  1794.  
  1795.     @@LExit:
  1796.   pop    di si ds
  1797.   leave
  1798.   retf
  1799. ENDP
  1800.  
  1801.  
  1802. ;*****
  1803. ;***** clearGraphics
  1804. ;*****
  1805.  
  1806. PROC    C    clearGraphics
  1807.     ARG    colour:BYTE
  1808.   push    di
  1809.   les    di,[outAddr]
  1810.   mov    cx,32000
  1811.   mov    al,[colour]
  1812.   mov    ah,al
  1813.   rep    stosw
  1814.   pop    di
  1815.   leave
  1816.   retf
  1817. ENDP
  1818.  
  1819. ENDS
  1820. END